package com.example.java_gobang.API;


import com.example.java_gobang.game.MatchRequest;
import com.example.java_gobang.game.MatchResponse;
import com.example.java_gobang.game.Matcher;
import com.example.java_gobang.game.OnlineUserManager;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: LXW
 * Date: 2022-08-05
 * Time: 14:06
 */
@Component
// 通过这个类来处理匹配功能
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private Matcher matcher;

    /**
     * 连接成功后的操作
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 1. 拿到用户信息.
        User user = (User) session.getAttributes().get("user");
        int userId = user.getUserId();
        if (user == null) {
            // 拿不到用户的登录信息, 说明玩家未登录就进入游戏大厅了.
            // 则返回错误信息并关闭连接
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("玩家尚未登录!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        // 2. 检查玩家的上线状态
        if (onlineUserManager.getFromGameHall(userId) != null
                || onlineUserManager.getSessionFromGameRoom(userId) != null) {
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("禁止多开游戏大厅页面!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        // 3. 设置玩家上线状态
        onlineUserManager.enterGameHall(userId, session);
        System.out.println("玩家进入匹配页面: " + userId);
    }

    /**
     * 处理连接过程中客户端发来的请求
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 1. 拿到用户信息.
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            System.out.println("[onMessage] 玩家尚未登录!");
            return;
        }
        System.out.println("开始匹配: " + user.getUserId() + " message: " + message.toString());
        // 2. 解析读到的数据为 json 对象
        MatchRequest request = objectMapper.readValue(message.getPayload(), MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            matcher.add(user);
            response.setMessage("startMatch");
        } else if (request.getMessage().equals("stopMatch")) {
            matcher.remove(user);
            response.setMessage("stopMatch");
        } else {
            // 匹配失败
            response.setOk(false);
            response.setReason("非法的匹配请求!");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    /**
     * 处理连接中断的操作
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            System.out.println("[onError] 玩家尚未登录!");
            return;
        }
        WebSocketSession existSession = onlineUserManager.getFromGameHall(user.getUserId());
        if (existSession != session) {
            System.out.println("当前的会话不是玩家游戏中的会话, 不做任何处理!");
            return;
        }
        System.out.println("匹配页面连接出现异常! userId: " + user.getUserId() + ", message: " + exception.getMessage());
        onlineUserManager.exitGameHall(user.getUserId());
        // 如果玩家在匹配中, 则关闭页面时把玩家移出匹配队列
        matcher.remove(user);
    }

    /**
     * 处理断开连接的操作
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            System.out.println("[onClose] 玩家尚未登录!");
            return;
        }
        WebSocketSession existSession = onlineUserManager.getFromGameHall(user.getUserId());
        if (existSession != session) {
            System.out.println("当前的会话不是玩家游戏中的会话, 不做任何处理!");
            return;
        }
        System.out.println("玩家离开匹配页面: " + user.getUserId());
        onlineUserManager.exitGameHall(user.getUserId());
        // 如果玩家在匹配中, 则关闭页面时把玩家移出匹配队列
        matcher.remove(user);
    }
}
